import base64
import os
import zipfile
from tkinter import filedialog, Tk, Button, Label, messagebox

def encode_file(filepath):
    with open(filepath, "rb") as f:
        encoded = base64.b64encode(f.read())
    return encoded

def decode_content(content):
    return base64.b64decode(content)

def save_single_file(encoded, default_filename):
    save_path = filedialog.asksaveasfilename(
        title="保存为Base64格式文件",
        defaultextension=".b64",
        initialfile=default_filename + ".b64",
        filetypes=[("Base64文件", "*.b64"), ("所有文件", "*.*")]
    )
    if save_path:
        with open(save_path, "wb") as f:
            f.write(encoded)
        messagebox.showinfo("保存成功", f"文件已保存到: {save_path}")

def save_multiple_files_zipped(encoded_files):
    zip_path = filedialog.asksaveasfilename(
        title="保存为压缩文件",
        defaultextension=".zip",
        initialfile="压缩文件名.zip",
        filetypes=[("压缩文件", "*.zip"), ("所有文件", "*.*")]
    )
    if zip_path:
        with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
            for filename, encoded in encoded_files.items():
                zipf.writestr(filename, encoded)
        messagebox.showinfo("保存成", f"压缩文件已保存到: {zip_path}")

def encode_files():
    file_paths = filedialog.askopenfilenames(title="请选择文件进行Base64编码")
    if not file_paths:
        return

    overwrite = messagebox.askyesno("覆盖文件", "确定要覆盖原文件?")
    if overwrite:
        for filepath in file_paths:
            encoded = encode_file(filepath)
            with open(filepath, "wb") as f:
                f.write(encoded)
        messagebox.showinfo("覆盖成功", "选择的文件已经被覆写为Base64格式.")
    else:
        if len(file_paths) == 1:
            encoded = encode_file(file_paths[0])
            filename = os.path.splitext(os.path.basename(file_paths[0]))[0]
            save_single_file(encoded, filename)
        else:
            encoded_files = {}
            for path in file_paths:
                full_name = os.path.basename(path)
                encoded_files[full_name] = encode_file(path)
            save_multiple_files_zipped(encoded_files)

def decode_files():
    file_paths = filedialog.askopenfilenames(title="多选Base64格式文件或者一个压缩包文件进行解码")
    if not file_paths:
        return

    if len(file_paths) == 1 and file_paths[0].lower().endswith(".zip"):
        filepath = file_paths[0]
        overwrite = messagebox.askyesno("Overwrite", "Do you want to overwrite the original files?")
        with zipfile.ZipFile(filepath, "r") as zipf:
            inner_files = zipf.namelist()
            if not inner_files:
                messagebox.showinfo("未找到文", "在压缩包中没有找到文件!")
                return
            if overwrite:
                temp_extract_path = os.path.dirname(filepath)
                for name in inner_files:
                    data = decode_content(zipf.read(name))
                    with open(os.path.join(temp_extract_path, name), "wb") as f:
                        f.write(data)
                messagebox.showinfo("覆盖成功", "压缩文件已经解码并保存到原文件夹中")
            else:
                extract_dir = filedialog.askdirectory(title="选择文件夹保存解码后的文件")
                if not extract_dir:
                    return
                for name in inner_files:
                    data = decode_content(zipf.read(name))
                    with open(os.path.join(extract_dir, os.path.basename(name)), "wb") as f:
                        f.write(data)
                messagebox.showinfo("解码成功", f"文件解码到: {extract_dir}")
    else:
        overwrite = messagebox.askyesno("覆盖文", "你确定要覆盖原文件吗?")
        for filepath in file_paths:
            with open(filepath, "rb") as f:
                content = f.read()
            decoded = decode_content(content)
            if overwrite:
                with open(filepath, "wb") as f:
                    f.write(decoded)
            else:
                filename = os.path.splitext(os.path.basename(filepath))[0]
                save_path = filedialog.asksaveasfilename(
                    title=f"Save Decoded File for {filename}",
                    initialfile=filename,
                    filetypes=[("所有文件", "*.*")]
                )
                if save_path:
                    with open(save_path, "wb") as f:
                        f.write(decoded)
        messagebox.showinfo("解码成功", "选择的文件已经成功解码.")

# GUI Setup
root = Tk()
root.title("Base64文件编码/解码")
window_width = 400
window_height = 220
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
position_top = int((screen_height - window_height) / 2)
position_left = int((screen_width - window_width) / 2)
root.geometry(f"{window_width}x{window_height}+{position_left}+{position_top}")

# Label(root, text="Base64文件编码/解码", font=("Arial", 14)).pack(pady=10)
Label(root, text="Base64文件编码/解码", font=("宋体", 14)).pack(pady=10)
Button(root, text="选择文件编码", command=encode_files, height=2, width=30).pack(pady=5)
Button(root, text="选择文件解码", command=decode_files, height=2, width=30).pack(pady=5)

root.mainloop()